﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Windows.Forms;
namespace WenSkin.Controls
{
    [ToolboxBitmap(typeof(TreeView))]
    public partial class WenTreeView : TreeView
    {
        public WenTreeView()
        {
            InitializeComponent();
            this.DrawMode = TreeViewDrawMode.OwnerDrawText;
            this.ItemHeight = 30;
            this.BackColor = Color.FromArgb(45, 45, 48);
            this.FullRowSelect = true;
        }

        #region 委托事件
        public delegate void TreeNodeDrawEventHandler(object sender, DragTreeNodeEventArgs e);
        public delegate void WenTreeViewEventHandler(object sender, WenTreeViewEventArgs e);

        [Category("Wen")]
        [Description("拖拽节点发生事件")]
        public event TreeNodeDrawEventHandler TreeNodeDrag;
        [Category("Wen")]
        [Description("节点被点击事件")]
        public event WenTreeViewEventHandler TreeNodeItemClick;
        [Category("Wen")]
        [Description("节点勾选事件")]
        public event WenTreeViewEventHandler TreeNodeCheck;
        #endregion

        #region 私有属性
        private List<TreeNode> checkBoxSelected;
        private DataListColumnCollection columns;
        private TreeDataSourceNode treeDataSourceNode;

        private object dataSource { get; set; }

        private StringFormat StringConters { get; set; }
            = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap)
            {
                LineAlignment = StringAlignment.Center,
                Trimming = StringTrimming.EllipsisCharacter
            };

        #endregion

        #region 公有属性
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Category("Wen")]
        [Description("列数据")]
        [Editor(typeof(Design.Editor.WenCollectionEditor),typeof(UITypeEditor))]
        public DataListColumnCollection Columns => columns ??= new DataListColumnCollection(this);


        [Category("Wen")]
        [Description("绑定数据Text默认值")]
        [DefaultValue(null)]
        public string DefaultTextColumn { get; set; }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Category("Wen")]
        [Description("绑定数据节点信息设置")]
        [DefaultValue(false)]
        public TreeDataSourceNode TreeDataSourceNode => treeDataSourceNode ??= new TreeDataSourceNode();

        [Category("Wen")]
        [Description("获取勾选项")]
        [Browsable(false)]
        public List<TreeNode> CheckBoxSelected => checkBoxSelected ??= new List<TreeNode>();

        [Browsable(false), DefaultValue(null)]
        public object DataSource
        {
            get => dataSource;
            set
            {
                dataSource = value;
                DataBind();
            }
        }
        #endregion

        #region 绑定数据
        private void DataBind()
        {
            if (dataSource == null)
                return;
            this.Nodes.Clear();
            //判定是否是数据绑定输结构模式
            if (TreeDataSourceNode.TreeDataSource)
            {
                bindDataRows.Clear();
                if (dataSource is DataTable dt)
                    DataBindTreeNode(dt, this.Nodes, TreeDataSourceNode.RootContent);
            }
            //若不是直接绑定数据
            else
            {
                switch (dataSource)
                {
                    case DataTable dt:
                        DataBind(dt);
                        break;
                    case DataSet ds:
                        DataBind(ds.Tables[0]);
                        break;
                    case IList lists:
                        foreach (var item in lists)
                        {
                            var infos = item.GetType().GetProperties().ToList();
                            WenTreeNode node = new WenTreeNode(this)
                            {
                                Tag = item,
                                Text = DefaultTextColumn == null ? 
                                item.GetType().GetProperties()[0]?.GetValue(item, null)?.ToString() : 
                                infos.Find(a => a.Name.ToUpper() == DefaultTextColumn.ToUpper())?.GetValue(item, null)?.ToString(),
                            };
                            foreach (DataListColumn column in Columns)
                            {
                                node.Cells.Add(new WenTreeViewCell(column.CloumnName, infos.Find(a => a.Name.ToUpper() == column.CloumnName.ToUpper())?.GetValue(item, null)?.ToString()));
                            }
                            this.Nodes.Add(node);
                        }
                        break;
                    default:
                        break;
                }

            }
            void DataBind(DataTable dt)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    WenTreeNode node = new WenTreeNode(this)
                    {
                        Tag = dr,
                        Text = DefaultTextColumn == null ? dr[0]?.ToString() : dt.Columns.Contains(DefaultTextColumn) ? dr[DefaultTextColumn]?.ToString() : null,
                    };
                    foreach (DataListColumn column in Columns)
                    {
                        node.Cells.Add(new WenTreeViewCell(column.CloumnName, dt.Columns.Contains(column.CloumnName) ? dr[column.CloumnName] : null));
                    }   
                    this.Nodes.Add(node);
                }
            }
            //折叠全部数据
            this.CollapseAll();
        }

        List<DataRow> bindDataRows = new List<DataRow>();

        private void DataBindTreeNode(DataTable dt, TreeNodeCollection nodes, string value)
        {
            DataRow[] rows = dt.Select($"{TreeDataSourceNode.ParentNode}=\'{value}\'");

            foreach (DataRow dr in rows)
            {
                if (bindDataRows.Contains(dr))
                    continue;
                WenTreeNode node = new WenTreeNode(this)
                {
                    Tag = dr,
                    Text = DefaultTextColumn == null ? dr[0]?.ToString() : dt.Columns.Contains(DefaultTextColumn) ? dr[DefaultTextColumn]?.ToString() : null,
                };
                foreach (DataListColumn column in Columns)
                {
                    if (dt.Columns.Contains(column.CloumnName))
                    {
                        WenTreeViewCell cell = new WenTreeViewCell(column.CloumnName, dr[column.CloumnName]);
                        cell.ValueChange += (s, e) =>
                        {
                            dr[column.CloumnName] = e.Message;
                        };
                        node.Cells.Add(cell);
                    }
                }
                nodes.Add(node);

                string parentValue = dr[TreeDataSourceNode.ChildNode]?.ToString();
                DataBindTreeNode(dt, node.Nodes, parentValue);
                bindDataRows.Add(dr);
            }
        }

        #endregion

        #region 重绘事件
        protected override void OnPaint(PaintEventArgs e)
        {
        }
        protected override void OnDrawNode(DrawTreeNodeEventArgs e)
        {
            //base.OnDrawNode(e);
            Graphics g = e.Graphics;
            g.SetGDIHigh();
            Rectangle rec = new Rectangle(e.Bounds.X, e.Bounds.Y - 1, Width - e.Bounds.X, e.Bounds.Height + 1);

            //正在需要绘制的项目
            TreeNode node = e.Node;

            //此项还不清楚是
            if (rec.X < 1)
                return;


            //获取当前选中项目
            TreeNode selectNode = this.SelectedNode;

            if (selectNode == node)
                g.FillRectangle(new SolidBrush(Color.FromArgb(63, 63, 70)), rec);
            else
                //整行设置重绘背景颜色
                g.FillRectangle(new SolidBrush(this.BackColor), rec);

            //绘制一条长线
            g.DrawLine(Pens.Gray,
                rec.X,
                rec.Y + rec.Height - 1,
                rec.X + rec.Width,
                rec.Y + rec.Height - 1);

            //设置文字颜色，和单元格样式
            var brus = Brushes.White;
            if (selectNode == node)
                brus = Brushes.White;

            //当行数据为空或者其他数据值为空的时候显示文本
            if(node is WenTreeNode wennode)
            {
                if (Columns.Count == 0)
                {
                    g.DrawString(node.Text, Font, brus, rec, StringConters);
                    return;
                }
                int rowsumwidth = rec.X;
                foreach (DataListColumn c in Columns)
                {
                    var recleft = rowsumwidth;

                    int index = Columns.IndexOf(c);
                    //绘制宽度
                    int width = c.Width;
                    if (index == 0)
                        width = c.Width - node.Level * Indent;

                    rowsumwidth += width;
                    Rectangle rectangle = new Rectangle(recleft, rec.Y, width, ItemHeight - 1);

                    string text = wennode.Cells[c.CloumnName]?.Value?.ToString();

                    g.DrawString(text, Font, brus, rectangle, StringConters);
                }
            }
            else
            {
                g.DrawString(node.Text, Font, brus, rec, StringConters);
            }
        }
        #endregion

        #region 鼠标点击事件
        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
            TreeNode node = this.GetNodeAt(e.X, e.Y);
            this.SelectedNode = node;
            TreeNodeItemClick?.Invoke(this, new WenTreeViewEventArgs(node) { TreeNodes = CheckBoxSelected });
        }
        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            base.OnMouseDoubleClick(e);
            this.SelectedNode = this.GetNodeAt(e.X, e.Y);

            Rectangle rec = this.SelectedNode.Bounds;
            if (rec.Contains(e.Location))
                return;

            if (this.SelectedNode.IsExpanded)
                this.SelectedNode.Collapse();
            else
                this.SelectedNode.Expand();
        }
        #endregion

        #region 拖动移动节点
        protected override void OnItemDrag(ItemDragEventArgs e)
        {
            base.OnItemDrag(e);
            if (e.Button == MouseButtons.Left)
            {
                if(e.Item  is TreeNode node)
                this.DoDragDrop(node, DragDropEffects.Move);
            }
        }
        protected override void OnDragEnter(DragEventArgs e)
        {
            base.OnDragEnter(e);
            if (e.Data.GetDataPresent(typeof(TreeNode))|| e.Data.GetDataPresent(typeof(WenTreeNode)))
            {
                e.Effect = DragDropEffects.Move;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        protected override void OnDragDrop(DragEventArgs e)
        {
            base.OnDragDrop(e);

            var moveNode = (e.Data.GetData(typeof(WenTreeNode)) as WenTreeNode) ?? (e.Data.GetData(typeof(TreeNode)) as TreeNode);

            //根据鼠标坐标确定要移动到的目标节点
            Point pt;
            TreeNode targeNode;
            pt = this.PointToClient(new Point(e.X, e.Y));
            targeNode = this.GetNodeAt(pt);


            //判定节点情况是否可移动
            if (moveNode == null || targeNode == null || targeNode == moveNode || BoolMoneNode(moveNode, targeNode) || targeNode == moveNode.Parent)
                return;

            if (!OnTreeNodeDraw(moveNode, targeNode))
                return;

            moveNode.Remove();
            targeNode.Nodes.Add(moveNode);


            //更新当前拖动的节点选择
            this.SelectedNode = moveNode;
            //展开目标节点,便于显示拖放效果
            targeNode.Expand();

 
        }
        //判定移动的节点是否是节点的子节点
        private bool BoolMoneNode(TreeNode node, TreeNode targeNode)
        {

            return nodes(node).Exists(a => a == targeNode);
            List<TreeNode> nodes(TreeNode nes)
            {
                List<TreeNode> ns = new List<TreeNode>();
                if(nes?.Nodes.Count>0)
                    foreach (TreeNode no in nes.Nodes)
                    {
                        if (no.Nodes.Count > 0)
                            ns.AddRange(nodes(no));
                        ns.Add(no);
                    }
                return ns;
            }
        }

        public bool OnTreeNodeDraw(TreeNode node, TreeNode targeNode)
        {
            var e = new DragTreeNodeEventArgs(node, targeNode);
            TreeNodeDrag?.Invoke(this, e);
            return e.State;            
        }
        #endregion

        //若tag 绑定值得情况，将datarowview的值更新
        protected override void OnAfterLabelEdit(NodeLabelEditEventArgs e)
        {
            base.OnAfterLabelEdit(e);

            if (e.Label == null)
                return;
            if (e.Node is WenTreeNode node)
            {
                node.Cells[DefaultTextColumn].Value = e.Label;
            }
        }

        #region 勾选引发事件
        protected override void OnAfterCheck(TreeViewEventArgs e)
        {
            base.OnAfterCheck(e);
            if (e.Node.Checked)
            {
                if (!CheckBoxSelected.Contains(e.Node))
                {
                    CheckBoxSelected.Add(e.Node);
                }
            }
            else
            {
                if (CheckBoxSelected.Contains(e.Node))
                {
                    CheckBoxSelected.Remove(e.Node);
                }
            }
            WenTreeViewEventArgs wenTreeViewEventArgs = new WenTreeViewEventArgs(e.Node, e.Action)
            {
                TreeNodes = CheckBoxSelected
            };

            TreeNodeCheck?.Invoke(this, wenTreeViewEventArgs);
        }
        #endregion


        [TypeConverter(typeof(ExpandableObjectConverter))]
        public class DataListColumn
        {
            public DataListColumn()
            {
            }
            [DefaultValue("Name")]
            public string Name { get; set; } = "Name";

            [DefaultValue("CloumnName")]
            public string CloumnName { get; set; } = "CloumnName";
            [DefaultValue("标题")]
            public string Text { get; set; } = "标题";

            [DefaultValue(120)]
            public int Width { get; set; } = 120;
            public override string ToString()
            {
                if (Name != Text)
                    return $"{Name}[{Text}]";
                else
                    return Name;
            }
        }
        public class DataListColumnCollection : WenCollection
        {
            private readonly WenTreeView owner;
            public DataListColumnCollection(WenTreeView owner)
            {
                this.owner = owner;
            }
            public DataListColumn this[int index] => Items.Count <= index ? null : Items[index] as DataListColumn;
        }
        public class WenTreeViewCell
        {
            private object value;

            public event WenSkin.EventClass.MessageEventHandler ValueChange;
            public WenTreeViewCell()
            {
            }

            public WenTreeViewCell(string name, object value)
            {
                Name = name;
                Value = value;
            }

            public string Name { get; set; }
            public object Value
            {
                get => value; 
                set
                {
                    this.value = value;
                    ValueChange?.Invoke(this, new EventClass.MessageEventArgs(value?.ToString()));
                }
            }
        }
        public class WenTreeViewCellCollection : WenCollection
        {
            public WenTreeViewCell this[int index]
            {
                get => Items.Count <= index ? null : (WenTreeViewCell)Items[index];
                set
                {
                    if (Items.Count <= index)
                        return;

                    Items[index] = value;
                }
            }
            public WenTreeViewCell this[string key]
            {
                get
                {
                    foreach (var item in Items)
                    {
                        if (item is WenTreeViewCell cell)
                        {
                            if (cell.Name.ToUpper() == key.ToUpper())
                            {
                                return cell;
                            }
                        }
                    }
                    return null;
                }
            }

        }

        public class WenTreeNode : TreeNode
        {
            private readonly WenTreeView owner;
            public WenTreeNode():base()
            {
            }
            public WenTreeNode(WenTreeView owner):base()
            {
                this.owner = owner;
            }

            private WenTreeViewCellCollection cells;
            public WenTreeViewCellCollection Cells => cells ??= new WenTreeViewCellCollection();
        }
        public class WenTreeViewEventArgs : TreeViewEventArgs
        {
            public WenTreeViewEventArgs(TreeNode node) : base(node)
            {
            }
            public WenTreeViewEventArgs(TreeNode node, TreeViewAction action) : base(node, action)
            {

            }
            public List<TreeNode> TreeNodes { get; set; }
        }
        public class DragTreeNodeEventArgs : TreeViewEventArgs
        {
            public DragTreeNodeEventArgs(TreeNode node,TreeNode targe) : base(node)
            {
                this.TargeTreeNode = targe;
            }

            public TreeNode TargeTreeNode { get;private set; }
            public bool State { get; set; } = true;
        }

    }
}
